#include "Queue.h"

#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
//队列实现
void QueueInit(Queue* q)
{
	assert(q);
	q->head = NULL;
	q->tail = NULL;
	q->size = 0;
}

void QueueDestroy(Queue* q)
{
	assert(q);
	while (q->head)
	{
		Node* tmp = q->head->next;
		free(q->head);
		q->head = tmp;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

Node* CreateNode()
{
	Node* newnode = (Node*)malloc(sizeof(Node));
	if (NULL == newnode)
	{
		perror("malloc");
		return NULL;
	}
	return newnode;
}

bool QueuePush(Queue* q, QueueDataType x)
{
	assert(q);
	Node* newnode = CreateNode();
	if (NULL == newnode)
		return false;
	newnode->val = x;
	newnode->next = NULL;
	if (NULL == q->head) //不能写为NULL == q->head == q->tail
	{
		q->head = q->tail = newnode;
	}
	else
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
	++(q->size);
	return true;
}

bool QueuePop(Queue* q)
{
	assert(q);
	if (QueueEmpty(q))  //或者是assert(!QueueEmpty(q));
		return false;
	if (NULL == q->head->next)
	{
		free(q->head);
		q->head = q->tail = NULL; //注意：Pop队列中的元素要特殊处理队列元素个数为1的情况！，如果不处理q->head就会变为NULL,对于
		                          //QueueDestroy操作就会出现错误，和对下一次QueuePop操作会造成q->head == NULL , head->next会造成错误
	}
	else
	{
		Node* tmp = q->head->next;
		free(q->head);
		q->head = tmp;
	}
	--(q->size);
	return true;
}

int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}

bool QueueEmpty(Queue* q)
{
	assert(q);
	return 0 == q->size;
}

QueueDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q)); //注意：这里必须要判断队列里是否有元素,当有数据的时候才可以
	return q->head->val;
}

QueueDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->tail->val;
}